
import machine
import time
import math
import struct
from micropython import const

class MicroBlueError(Exception):
    pass


def my_uuid():
    uid = machine.unique_id()
    return ''.join(['{:02x}'.format(b) for b in uid])


class DsPwmServo:
    def __init__(self, pin):
        if my_uuid() not in ['6825ddf0eb60', '6825ddf0fd3c', '6825ddf11278']:
            raise MicroBlueError("主板序列号未注册，请联系微蓝课堂")
        self.servo_pin = machine.Pin(pin, machine.Pin.OUT)

    def init_pwm(self):
        self.pwm = machine.PWM(self.servo_pin, freq=50)

    def motor_run(self, speed, clockwise=True):
        """ 500μs~CCW逆时针; 1500μs~停；2500μs~CW顺时针
        - 信号周期（Signal Period）：20ms
        - 脉冲宽度（Pulse Width）：500μs-2500μs
        """
        self.init_pwm()
        speed = max(0, min(100, speed))
        
        if clockwise:  # 顺时针：脉冲宽度1500→2500μs
            us = 1500 + 1000 * speed / 100
        else:          # 逆时针：脉冲宽度1500→500μs
            us = 1500 - 1000 * speed / 100
        duty = int(us * 1024 / 20000)
        self.pwm.duty(duty)

    def servo_180(self, angle):
        """
        - 信号周期（Signal Period）：20ms
        - 脉冲宽度（Pulse Width）：500μs-2500μs 
        """
        self.init_pwm()
        angle = max(0, min(180, angle))
        us = math.floor((angle) * 2000 / 180) + 500
        duty = int(us / 20000 * 1023)
        self.pwm.duty(duty)

    def servo_270(self, angle):
        """
        - 信号周期（Signal Period）：20ms
        - 脉冲宽度（Pulse Width）：500μs-2500μs 
        """
        self.init_pwm()
        angle = max(0, min(270, angle))
        us = math.floor((angle) * 2000 / 270) + 500
        duty = int(us / 20000 * 1023)
        self.pwm.duty(duty)

    def deinit(self):
        """释放PWM资源"""
        self.pwm.deinit()
